<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>前端设计模式 | 小朱的网站</title>
    <meta name="generator" content="VuePress 1.8.2">
    <link rel="icon" href="/fav.ico">
    <link rel="stylesheet" href="/css/katex.min.css">
    <link rel="stylesheet" href="/css/github-markdown.min.css">
    <meta name="description" content="网页测试">
    
    <link rel="preload" href="/assets/css/0.styles.7f64417e.css" as="style"><link rel="preload" href="/assets/js/app.adf242e6.js" as="script"><link rel="preload" href="/assets/js/2.8cf67c90.js" as="script"><link rel="preload" href="/assets/js/22.a1f4c10c.js" as="script"><link rel="prefetch" href="/assets/js/10.15f163a4.js"><link rel="prefetch" href="/assets/js/11.a27afcec.js"><link rel="prefetch" href="/assets/js/12.27eb6ae9.js"><link rel="prefetch" href="/assets/js/13.0264e853.js"><link rel="prefetch" href="/assets/js/14.0e338da5.js"><link rel="prefetch" href="/assets/js/15.18feaada.js"><link rel="prefetch" href="/assets/js/16.131aa977.js"><link rel="prefetch" href="/assets/js/17.bc458c69.js"><link rel="prefetch" href="/assets/js/18.a943de2b.js"><link rel="prefetch" href="/assets/js/19.28b106c6.js"><link rel="prefetch" href="/assets/js/20.3b5e14bb.js"><link rel="prefetch" href="/assets/js/21.76010c7a.js"><link rel="prefetch" href="/assets/js/23.c62fd73c.js"><link rel="prefetch" href="/assets/js/24.29fa4cff.js"><link rel="prefetch" href="/assets/js/25.d0caf08f.js"><link rel="prefetch" href="/assets/js/26.fcbe8a2e.js"><link rel="prefetch" href="/assets/js/27.028c550c.js"><link rel="prefetch" href="/assets/js/28.94fcec24.js"><link rel="prefetch" href="/assets/js/29.d2fd21a3.js"><link rel="prefetch" href="/assets/js/3.7b0f057b.js"><link rel="prefetch" href="/assets/js/30.e219df5c.js"><link rel="prefetch" href="/assets/js/31.26e4967d.js"><link rel="prefetch" href="/assets/js/32.dd5db7fd.js"><link rel="prefetch" href="/assets/js/33.541725d2.js"><link rel="prefetch" href="/assets/js/34.7269715f.js"><link rel="prefetch" href="/assets/js/35.19b86b0e.js"><link rel="prefetch" href="/assets/js/36.240ce0fb.js"><link rel="prefetch" href="/assets/js/37.3b5e2f37.js"><link rel="prefetch" href="/assets/js/4.60158cd1.js"><link rel="prefetch" href="/assets/js/5.6154fd2f.js"><link rel="prefetch" href="/assets/js/6.d914717c.js"><link rel="prefetch" href="/assets/js/7.e50321c3.js"><link rel="prefetch" href="/assets/js/8.50a0932a.js"><link rel="prefetch" href="/assets/js/9.5e7ea4bd.js">
    <link rel="stylesheet" href="/assets/css/0.styles.7f64417e.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/" class="home-link router-link-active"><!----> <span class="site-name">小朱的网站</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="https://datav.aliyuncs.com/share/c5fe85f805b0425186d01be47dc34322" target="_blank" rel="noopener noreferrer" class="nav-link external">
  数据可视化实践
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></div><div class="nav-item"><a href="/front-end/" class="nav-link router-link-active">
  前端技术小结
</a></div><div class="nav-item"><a href="/office/" class="nav-link">
  高效办公方法
</a></div><div class="nav-item"><a href="/general/" class="nav-link">
  通用知识速查
</a></div><div class="nav-item"><a href="/CPC/" class="nav-link">
  政治教育学习
</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="⭐️资源" class="dropdown-title"><span class="title">⭐️资源</span> <span class="arrow down"></span></button> <button type="button" aria-label="⭐️资源" class="mobile-dropdown-title"><span class="title">⭐️资源</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="https://echarts.apache.org/examples/zh/index.html" target="_blank" rel="noopener noreferrer" class="nav-link external">
  echarts示例
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="https://report.anji-plus.com/report-doc/" target="_blank" rel="noopener noreferrer" class="nav-link external">
  AJ-Report
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="https://help.aliyun.com/document_detail/86874.html" target="_blank" rel="noopener noreferrer" class="nav-link external">
  阿里云DataV
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="https://gitee.com/all-about-git" target="_blank" rel="noopener noreferrer" class="nav-link external">
  码云Git大全
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="https://www.dedao.cn/" target="_blank" rel="noopener noreferrer" class="nav-link external">
  得到APP网页版
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="https://edu.dji.com/hub/docs" target="_blank" rel="noopener noreferrer" class="nav-link external">
  大疆教育平台
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></div></div> <!----></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"><div class="nav-item"><a href="https://datav.aliyuncs.com/share/c5fe85f805b0425186d01be47dc34322" target="_blank" rel="noopener noreferrer" class="nav-link external">
  数据可视化实践
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></div><div class="nav-item"><a href="/front-end/" class="nav-link router-link-active">
  前端技术小结
</a></div><div class="nav-item"><a href="/office/" class="nav-link">
  高效办公方法
</a></div><div class="nav-item"><a href="/general/" class="nav-link">
  通用知识速查
</a></div><div class="nav-item"><a href="/CPC/" class="nav-link">
  政治教育学习
</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="⭐️资源" class="dropdown-title"><span class="title">⭐️资源</span> <span class="arrow down"></span></button> <button type="button" aria-label="⭐️资源" class="mobile-dropdown-title"><span class="title">⭐️资源</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="https://echarts.apache.org/examples/zh/index.html" target="_blank" rel="noopener noreferrer" class="nav-link external">
  echarts示例
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="https://report.anji-plus.com/report-doc/" target="_blank" rel="noopener noreferrer" class="nav-link external">
  AJ-Report
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="https://help.aliyun.com/document_detail/86874.html" target="_blank" rel="noopener noreferrer" class="nav-link external">
  阿里云DataV
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="https://gitee.com/all-about-git" target="_blank" rel="noopener noreferrer" class="nav-link external">
  码云Git大全
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="https://www.dedao.cn/" target="_blank" rel="noopener noreferrer" class="nav-link external">
  得到APP网页版
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="https://edu.dji.com/hub/docs" target="_blank" rel="noopener noreferrer" class="nav-link external">
  大疆教育平台
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></div></div> <!----></nav>  <ul class="sidebar-links"><li><a href="/front-end/javascript.html" class="sidebar-link">Javascript/ECMAScript 相关技术</a></li><li><a href="/front-end/pattern.html" aria-current="page" class="active sidebar-link">前端设计模式</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/front-end/pattern.html#javascript-设计模式" class="sidebar-link">javascript 设计模式</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/front-end/pattern.html#设计模式概念" class="sidebar-link">设计模式概念</a></li><li class="sidebar-sub-header"><a href="/front-end/pattern.html#题目一" class="sidebar-link">题目一</a></li><li class="sidebar-sub-header"><a href="/front-end/pattern.html#题目二" class="sidebar-link">题目二</a></li><li class="sidebar-sub-header"><a href="/front-end/pattern.html#题目三" class="sidebar-link">题目三</a></li><li class="sidebar-sub-header"><a href="/front-end/pattern.html#题目四" class="sidebar-link">题目四</a></li><li class="sidebar-sub-header"><a href="/front-end/pattern.html#题目五" class="sidebar-link">题目五</a></li></ul></li><li class="sidebar-sub-header"><a href="/front-end/pattern.html#结尾" class="sidebar-link">结尾</a></li><li class="sidebar-sub-header"><a href="/front-end/pattern.html#相关链接" class="sidebar-link">相关链接</a></li></ul></li><li><a href="/front-end/typescript.html" class="sidebar-link">学习 Typescript 实战开发</a></li><li><a href="/front-end/es6.html" class="sidebar-link">深入理解ES6</a></li><li><a href="/front-end/css.html" class="sidebar-link">css 实战学习</a></li><li><a href="/front-end/node.html" class="sidebar-link">Node.js深入浅出</a></li><li><a href="/front-end/design.html" class="sidebar-link">前端设计与可视化</a></li><li><a href="/front-end/npm.html" class="sidebar-link">npm常用命令</a></li><li><a href="/front-end/vuepress.html" class="sidebar-link">vuepress 基本配置</a></li><li><a href="/front-end/babel.html" class="sidebar-link">Babel详细学习</a></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><h1 id="前端设计模式"><a href="#前端设计模式" class="header-anchor">#</a> 前端设计模式</h1> <h2 id="javascript-设计模式"><a href="#javascript-设计模式" class="header-anchor">#</a> javascript 设计模式</h2> <p>主要结合实际例子说明以下三种模式:</p> <ul><li>策略模式</li> <li>发布 - 订阅模式</li> <li>装饰器模式</li> <li>适配器模式</li> <li>代理模式</li> <li>责任链模式</li></ul> <h3 id="设计模式概念"><a href="#设计模式概念" class="header-anchor">#</a> 设计模式概念</h3> <p>官方解释一点就是 : 模式是一种可服用的解决方案，用于解决软件设计中遇到的常见问题。</p> <p>我举的这个例子，你应该知道，什么是设计模式了吧？引用<a href="https://juejin.im/user/5b8df4ef6fb9a019b421e11c" target="_blank" rel="noopener noreferrer">修言<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>老哥的一句话 : <em>烹饪有菜谱，游戏有攻略，干啥都有一些能够让我们达到目标的 “套路”，在程序世界，编程的“套路” 就是设计模式。</em></p> <p>设计模式就是在软件设计、开发过程中，针对特定问题、场景的更优解决方案。</p> <h3 id="题目一"><a href="#题目一" class="header-anchor">#</a> 题目一</h3> <p>我们先来做一个题，很简单的，大家肯定都做过 <code>权限逻辑</code> 判断吧？</p> <p><strong>需求 : 只用当用户满足以下条件，才能看阿宽的这篇文章</strong></p> <p><img src="https://user-gold-cdn.xitu.io/2020/4/26/171b59bda9cc72cd?imageView2/0/w/1280/h/960/format/webp/ignore-error/1" alt=""></p> <p>给大家 <code>3min</code>，代码怎么写？ <strong>“ 呵，你这不是看不起老夫吗？老夫拿起键盘，就是 <code>if-else</code> 梭哈，直接带走，下一个 ! ”</strong></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">checkAuth</span><span class="token punctuation">(</span><span class="token parameter">data</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>data<span class="token punctuation">.</span>role <span class="token operator">!==</span> <span class="token string">'juejin'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'不是掘金用户'</span><span class="token punctuation">)</span>
    <span class="token keyword">return</span> <span class="token boolean">false</span>
  <span class="token punctuation">}</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>data<span class="token punctuation">.</span>grade <span class="token operator">&lt;</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'掘金等级小于 1 级'</span><span class="token punctuation">)</span>
    <span class="token keyword">return</span> <span class="token boolean">false</span>
  <span class="token punctuation">}</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>data<span class="token punctuation">.</span>job <span class="token operator">!==</span> <span class="token string">'FE'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'不是前端开发'</span><span class="token punctuation">)</span>
    <span class="token keyword">return</span> <span class="token boolean">false</span>
  <span class="token punctuation">}</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>data<span class="token punctuation">.</span>type <span class="token operator">!==</span> <span class="token string">'eat melons'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'不是吃瓜群众'</span><span class="token punctuation">)</span>
    <span class="token keyword">return</span> <span class="token boolean">false</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p>这段代码的问题在哪?</p> <ul><li>checkAuth 函数会爆炸 💥</li> <li>策略项无法复用</li> <li>违反开闭原则</li></ul> <p>聪明的小伙伴已经知道这里要讲的是什么模式了，对头！这里讲的就是 <code>策略模式</code>。那么什么是策略模式呢 ？</p> <h4 id="策略模式"><a href="#策略模式" class="header-anchor">#</a> 策略模式</h4> <p>定义 : 要实现某一个功能，有多种方案可以选择。我们定义策略，把它们一个个封装起来，并且使它们可以相互转换。</p> <p><strong>策略 + 组合，绝配啊，老哥！</strong></p> <p>我们用策略模式来改造以下这段逻辑 👇</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 维护权限列表</span>
<span class="token keyword">const</span> jobList <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">'FE'</span><span class="token punctuation">,</span> <span class="token string">'BE'</span><span class="token punctuation">]</span>

<span class="token comment">// 策略</span>
<span class="token keyword">var</span> strategies <span class="token operator">=</span> <span class="token punctuation">{</span>
  <span class="token function-variable function">checkRole</span><span class="token operator">:</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>value <span class="token operator">===</span> <span class="token string">'juejin'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">return</span> <span class="token boolean">true</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">return</span> <span class="token boolean">false</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token function-variable function">checkGrade</span><span class="token operator">:</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>value <span class="token operator">&gt;=</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">return</span> <span class="token boolean">true</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">return</span> <span class="token boolean">false</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token function-variable function">checkJob</span><span class="token operator">:</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>jobList<span class="token punctuation">.</span><span class="token function">indexOf</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span> <span class="token operator">&gt;</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">return</span> <span class="token boolean">true</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">return</span> <span class="token boolean">false</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token function-variable function">checkEatType</span><span class="token operator">:</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>value <span class="token operator">===</span> <span class="token string">'eat melons'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">return</span> <span class="token boolean">true</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">return</span> <span class="token boolean">false</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span>
</code></pre></div><p>我们已经写完了策略，接下来要做的就是验证了~</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 校验规则</span>
<span class="token keyword">var</span> <span class="token function-variable function">Validator</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">this</span><span class="token punctuation">.</span>cache <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>

  <span class="token comment">// 添加策略事件</span>
  <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function-variable function">add</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">value<span class="token punctuation">,</span> method</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>cache<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">return</span> strategies<span class="token punctuation">[</span>method<span class="token punctuation">]</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>

  <span class="token comment">// 检查</span>
  <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function-variable function">check</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>cache<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">let</span> valiFn <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>cache<span class="token punctuation">[</span>i<span class="token punctuation">]</span>
      <span class="token keyword">var</span> data <span class="token operator">=</span> <span class="token function">valiFn</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment">// 开始检查</span>
      <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>data<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token boolean">false</span>
      <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">return</span> <span class="token boolean">true</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p>此时，小彭同学需要进行权限验证的条件为 :</p> <ul><li>掘金用户</li> <li>掘金等级 1 级以上</li></ul> <p>那么代码就可以这么写 :</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 小彭使用策略模式进行操作</span>
<span class="token keyword">var</span> <span class="token function-variable function">compose1</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">var</span> validator <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Validator</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  <span class="token keyword">const</span> data1 <span class="token operator">=</span> <span class="token punctuation">{</span>
    role<span class="token operator">:</span> <span class="token string">'juejin'</span><span class="token punctuation">,</span>
    grade<span class="token operator">:</span> <span class="token number">3</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span>
  validator<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span>data1<span class="token punctuation">.</span>role<span class="token punctuation">,</span> <span class="token string">'checkRole'</span><span class="token punctuation">)</span>
  validator<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span>data1<span class="token punctuation">.</span>grade<span class="token punctuation">,</span> <span class="token string">'checkGrade'</span><span class="token punctuation">)</span>
  <span class="token keyword">const</span> result <span class="token operator">=</span> validator<span class="token punctuation">.</span><span class="token function">check</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  <span class="token keyword">return</span> result
<span class="token punctuation">}</span>
</code></pre></div><p>然后另一个小伙伴阿宽，他可能需要进行权限验证的条件为 :</p> <ul><li>掘金用户</li> <li>前端工程师</li></ul> <p>那么代码就可以这么写 :</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 阿宽使用策略模式进行操作</span>
<span class="token keyword">var</span> <span class="token function-variable function">compose2</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">var</span> validator <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Validator</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  <span class="token keyword">const</span> data2 <span class="token operator">=</span> <span class="token punctuation">{</span>
    role<span class="token operator">:</span> <span class="token string">'juejin'</span><span class="token punctuation">,</span>
    job<span class="token operator">:</span> <span class="token string">'FE'</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span>
  validator<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span>data2<span class="token punctuation">.</span>role<span class="token punctuation">,</span> <span class="token string">'checkRole'</span><span class="token punctuation">)</span>
  validator<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span>data2<span class="token punctuation">.</span>job<span class="token punctuation">,</span> <span class="token string">'checkJob'</span><span class="token punctuation">)</span>
  <span class="token keyword">const</span> result <span class="token operator">=</span> validator<span class="token punctuation">.</span><span class="token function">check</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  <span class="token keyword">return</span> result
<span class="token punctuation">}</span>
</code></pre></div><p>这是不是比一直疯狂写 <code>if-else</code> 好太多了呢？还有什么例子？表单验证啊 ~ 对于表单字段（名称、密码、邮箱、....）我们可以使用策略模式去设计优化它，想啥呢，赶紧动手试一下！我都已经手把手教你到这了~</p> <h4 id="什么时候用策略模式"><a href="#什么时候用策略模式" class="header-anchor">#</a> 什么时候用策略模式？</h4> <p>当你负责的模块，基本满足以下情况时</p> <ul><li>各判断条件下的策略相互独立且可复用</li> <li>策略内部逻辑相对复杂</li> <li>策略需要灵活组合</li></ul> <h3 id="题目二"><a href="#题目二" class="header-anchor">#</a> 题目二</h3> <p>前面还逼逼一下，这里直接给需求了 👇</p> <p><strong>需求 : 申请成功后，需要触发对应的订单、消息、审核模块对应逻辑</strong></p> <p><img src="https://user-gold-cdn.xitu.io/2020/4/26/171b599fe4feea3c?imageView2/0/w/1280/h/960/format/webp/ignore-error/1" alt=""></p> <p>机智如我，我会如何做呢？</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">applySuccess</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// 通知消息中心获取最新内容</span>
  MessageCenter<span class="token punctuation">.</span><span class="token function">fetch</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  <span class="token comment">// 更新订单信息</span>
  Order<span class="token punctuation">.</span><span class="token function">update</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  <span class="token comment">// 通知相关方审核</span>
  Checker<span class="token punctuation">.</span><span class="token function">alert</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div><p>不就这样写吗，还想咋滴！！！是的，这么写没得毛病，但是呢，我们来思考几个问题</p> <p>比如 <code>MessageCenter.fetch()</code> 是小彭写的，<strong>他大姨夫来了，心情不爽</strong>，把模块的方法名改了，现在叫 <code>MessageCenter.request()</code>，你咋办，你这块逻辑改呗~</p> <p>再比如，你和阿宽并行开发的，阿宽负责订单模块，你一气呵成写下这段代码，然后一运行，报错了，一询问，发现，<strong>原来阿宽昨晚去蹦迪了</strong>，原本今天应该完成的订单模块<code>Order.update()</code>，延迟一天，那你就只能先注释代码，等依赖的模块开发完了，你再回来添加这段逻辑咯~</p> <p>更可怕的是，你可能不只是涉及到这三个模块，maybe 还有很多模块，比如你申请成功，现在还需要上报申请日志，你总不能这样写吧？</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">applySuccess</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// 通知消息中心获取最新内容</span>
  MessageCenter<span class="token punctuation">.</span><span class="token function">fetch</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token comment">// 更新订单信息</span>
  Order<span class="token punctuation">.</span><span class="token function">update</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token comment">// 通知相关方审核</span>
  Checker<span class="token punctuation">.</span><span class="token function">alert</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token comment">// maybe 更多</span>
  Log<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token operator">...</span>
<span class="token punctuation">}</span>

</code></pre></div><p>到这里，我们的 <code>发布-订阅模式</code> 要按捺不住了。</p> <h4 id="发布-订阅模式"><a href="#发布-订阅模式" class="header-anchor">#</a> 发布 - 订阅模式</h4> <p><img src="https://user-gold-cdn.xitu.io/2020/4/26/171b5b0f46f42ee7?imageView2/0/w/1280/h/960/format/webp/ignore-error/1" alt=""></p> <p>啊哈哈哈，有没有觉得这个<code>EventEmitter</code>好熟悉啊，这不是面试常会问的？</p> <p>发布 - 订阅是一种消息范式，消息的发布者，不会将消息直接发送给特定的<code>订阅者</code>，而是通过消息通道广播出去，然后呢，订阅者通过订阅获取到想要的消息。</p> <p>我们用 发布 - 订阅模式 修改以下上边的代码 👇</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">const</span> <span class="token function-variable function">EventEmit</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">this</span><span class="token punctuation">.</span>events <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
  <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function-variable function">on</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">name<span class="token punctuation">,</span> cb</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>events<span class="token punctuation">[</span>name<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>events<span class="token punctuation">[</span>name<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>cb<span class="token punctuation">)</span>
    <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>events<span class="token punctuation">[</span>name<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span>cb<span class="token punctuation">]</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
  <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function-variable function">trigger</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">name<span class="token punctuation">,</span> <span class="token operator">...</span>arg</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>events<span class="token punctuation">[</span>name<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>events<span class="token punctuation">[</span>name<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">eventListener</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
        <span class="token function">eventListener</span><span class="token punctuation">(</span><span class="token operator">...</span>arg<span class="token punctuation">)</span>
      <span class="token punctuation">}</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p>上边我们写好了一个 <code>EventEmit</code>，然后我们的业务代码可以改成这样 ~</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">let</span> event <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">EventEmit</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
event<span class="token punctuation">.</span><span class="token function">trigger</span><span class="token punctuation">(</span><span class="token string">'success'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

MessageCenter<span class="token punctuation">.</span><span class="token function">fetch</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  event<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">'success'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'更新消息中心'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
Order<span class="token punctuation">.</span><span class="token function">update</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  event<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">'success'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'更新订单信息'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
Checker<span class="token punctuation">.</span><span class="token function">alert</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  event<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">'success'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'通知管理员'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

</code></pre></div><p>但是这样就没问题了吗？其实还是有弊端的，比如说，过多的使用发布订阅，就会导致难以维护调用关系。所以，还是看大家的设计吧，这里只是让大家知道，发布订阅模式是个啥~</p> <h4 id="什么时候用发布-订阅模式"><a href="#什么时候用发布-订阅模式" class="header-anchor">#</a> 什么时候用发布 - 订阅模式？</h4> <p>当你负责的模块，基本满足以下情况时</p> <ul><li>各模块相互独立</li> <li>存在一对多的依赖关系</li> <li>依赖模块不稳定、依赖关系不稳定</li> <li>各模块由不同的人员、团队开发</li></ul> <blockquote><p>我知道你有疑问，关于 观察者模式 VS 发布 - 订阅模式，这里我不讲它们的区分，下期再聊，或者自行资料查询</p></blockquote> <h3 id="题目三"><a href="#题目三" class="header-anchor">#</a> 题目三</h3> <p>这个题目，也有点难想啊，我直接说吧，主要讲 <strong>装饰器模式</strong>、<strong>适配器模式</strong>。</p> <h4 id="装饰器模式"><a href="#装饰器模式" class="header-anchor">#</a> 装饰器模式</h4> <blockquote><p>个人理解 : 是为了给一个函数赋能，增强它的某种能力，它能动态的添加对象的行为，也就是我传入的就是一个对象</p></blockquote> <blockquote><p>在 JS 世界中，世间万物，皆为对象</p></blockquote> <p>大家过年，都会买桔子树吧（不买的统一带走），意味 “大吉大利” 嘛，那么我们买了桔子树之后，都会往上边挂一些红包，摇身一变，“红包桔子树”，牛掰！这个的红包就是<strong>装饰器</strong>，它不对桔子树原有的功能产生影响。</p> <p>再举个 🌰，我现在写的这边文章，我只会写中文，但是各位看官中有英国小伙伴，那我不会写英文啊，所以我需要通过装饰器来赋予我写英文的能力</p> <p>你这不是在真实写代码中的啊，能不能举一个日常开发的 🌰，ok，那我来举一个，React 中的高阶组件 HOC</p> <p>了解 React 的都知道，高阶组件其实就是一个函数，接收一个组件作为参数，然后返回一个新的组件。</p> <p>那么我们现在写一个高阶组件 HOC，用它来装饰 <code>Target Component</code></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">'react'</span>

<span class="token keyword">const</span> <span class="token function-variable function">yellowHOC</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">WrapperComponent</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token keyword">class</span> <span class="token class-name">extends</span> React<span class="token punctuation">.</span>Component <span class="token punctuation">{</span>
    <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token punctuation">;</span><span class="token operator">&lt;</span>div style<span class="token operator">=</span><span class="token punctuation">{</span><span class="token punctuation">{</span> backgroundColor<span class="token operator">:</span> <span class="token string">'yellow'</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token operator">&gt;</span>
        <span class="token operator">&lt;</span>WrapperComponent <span class="token punctuation">{</span><span class="token operator">...</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">&gt;</span>
      <span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">&gt;</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> yellowHOC
</code></pre></div><p>定义了一个带有装饰黄色背景的高阶组件，我们用它来装饰目标组件</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">'react'</span>
<span class="token keyword">import</span> yellowHOC <span class="token keyword">from</span> <span class="token string">'./yellowHOC'</span>

<span class="token keyword">class</span> <span class="token class-name">TargetComponent</span> <span class="token keyword">extends</span> <span class="token class-name">Reac<span class="token punctuation">.</span>Compoment</span> <span class="token punctuation">{</span>
  <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token operator">&lt;</span>div<span class="token operator">&gt;</span><span class="token number">66666</span><span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">&gt;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token function">yellowHOC</span><span class="token punctuation">(</span>TargetComponent<span class="token punctuation">)</span>
</code></pre></div><p>你看，我们这不就用到了装饰器模式了嘛？什么，你还听不懂？那我最后再举一个例子，不知道这个例子，能不能帮助你们理解</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">const</span> <span class="token function-variable function">kuanWrite</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function-variable function">writeChinese</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'我只会写中文'</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token comment">// 通过装饰器给阿宽加上写英文的能力</span>
<span class="token keyword">const</span> <span class="token function-variable function">Decorator</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">old</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">this</span><span class="token punctuation">.</span>oldWrite <span class="token operator">=</span> old<span class="token punctuation">.</span>writeChinese
  <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function-variable function">writeEnglish</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'给阿宽赋予写英文的能力'</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
  <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function-variable function">newWrite</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">oldWrite</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">writeEnglish</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">const</span> oldKuanWrite <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">kuanWrite</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">const</span> decorator <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Decorator</span><span class="token punctuation">(</span>oldKuanWrite<span class="token punctuation">)</span>
decorator<span class="token punctuation">.</span><span class="token function">newWrite</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
</code></pre></div><h4 id="适配器模式"><a href="#适配器模式" class="header-anchor">#</a> 适配器模式</h4> <blockquote><p>个人理解，为了解决我们不兼容的问题，把一个类的接口换成我们想要的接口。</p></blockquote> <p>举个 🌰，我想听歌的时候，我发现我没带耳机，我的手机是 iphone 的，而现在我只有一个 Type-C 的耳机，为了能够听歌，我用了一个转换器（也就是适配器），然后我就可以开心的听歌了。</p> <p>再以上边的为例子，小彭来看阿宽写的文章，他只会看英文的，突然阿宽用日文来写，他看不懂，所以他需要通过适配器模块，去帮他转成日文，从而满足他的需求</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">/** ---------------新的代码------------ */</span>
<span class="token keyword">const</span> <span class="token function-variable function">kuanLanguage</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function-variable function">japaneseLanguage</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'阿宽写日文'</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">const</span> <span class="token function-variable function">pengLookLanguage</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function-variable function">lookLanguage</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'小彭只看得懂英文'</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token comment">// 通过适配器进行接口适配,从而满足我的需求</span>
<span class="token keyword">const</span> <span class="token function-variable function">AdapterLanguage</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">user</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">this</span><span class="token punctuation">.</span>language <span class="token operator">=</span> user<span class="token punctuation">.</span>lookLanguage
<span class="token punctuation">}</span>

<span class="token class-name">AdapterLanguage</span><span class="token punctuation">.</span>prototype <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">kuanLanguage</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token class-name">AdapterLanguage</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">japaneseLanguage</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">通过适配器, </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">也能听日文了</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token keyword">const</span> peng <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">pengLookLanguage</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">const</span> adapterPeng <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">AdapterLanguage</span><span class="token punctuation">(</span>peng<span class="token punctuation">)</span>
adapterPeng<span class="token punctuation">.</span><span class="token function">japaneseLanguage</span><span class="token punctuation">(</span><span class="token string">'小彭'</span><span class="token punctuation">)</span>
</code></pre></div><h3 id="题目四"><a href="#题目四" class="header-anchor">#</a> 题目四</h3> <p>我们再来讲一个叫做 <strong>代理模式</strong>，说到代理哈，我脑海里第一个浮现的词语 : “事件委托、事件代理”，这算吗？算哒。我举些 🌰，让大家知道代理模式是个啥玩意</p> <p>作为程序员嘛，女朋友比较难找，就算找到了，咱这么瘦弱，怕是保护不了啊，所以我花钱找了个保镖来保护我，稳妥。这就是代理模式。</p> <p>你翻墙吗？你能 google 吗？老实人哪会什么翻墙，我是不会的，会我也说我不会。其实正常来讲，我们直接访问 google 是无响应的。那怎么办呢，通过第三方代理服务器。VyprVPN ？ ExpressVPN ？懂 ？</p> <p>要说初中非主流三大巨头，莫过于 <code>许嵩、徐良、汪苏泷</code>了，去年想去看许嵩演唱会，好家伙，这个演唱会的门票都被抢光了，无奈之下，只能找黄牛，这里，黄牛就起了代理的作用，懂？</p> <p>程序世界的代理者也是如此，我们不直接操作原有对象，而是委托代理者去进行。代理者的作用，就是对我们的请求预先进行处理或转接给实际对象。</p> <blockquote><p>代理模式是为其它对象提供一种代理以<strong>控制</strong>这个对象的访问，具体执行的功能还是这个对象本身，就比如说，我们发邮件，通过代理模式，那么代理者可以控制，决定发还是不发，但具体发的执行功能，是外部对象所决定，而不是代理者决定。</p></blockquote> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 发邮件，不是qq邮箱的拦截</span>
<span class="token keyword">const</span> emailList <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">'qq.com'</span><span class="token punctuation">,</span> <span class="token string">'163.com'</span><span class="token punctuation">,</span> <span class="token string">'gmail.com'</span><span class="token punctuation">]</span>

<span class="token comment">// 代理</span>
<span class="token keyword">const</span> <span class="token function-variable function">ProxyEmail</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">email</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>emailList<span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span>email<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// 屏蔽处理</span>
  <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
    <span class="token comment">// 转发，进行发邮件</span>
    <span class="token function">SendEmail</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> email<span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">const</span> <span class="token function-variable function">SendEmail</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">email</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// 发送邮件</span>
<span class="token punctuation">}</span>

<span class="token comment">// 外部调用代理</span>
<span class="token function">ProxyEmail</span><span class="token punctuation">(</span><span class="token string">'cvte.com'</span><span class="token punctuation">)</span>
<span class="token function">ProxyEmail</span><span class="token punctuation">(</span><span class="token string">'ojbk.com'</span><span class="token punctuation">)</span>
</code></pre></div><p>下边再来举一个例子，来至 《JavaScript 设计模式与开发实践》</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 本体</span>
<span class="token keyword">var</span> domImage <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">var</span> imgEle <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">'img'</span><span class="token punctuation">)</span>
  document<span class="token punctuation">.</span>body<span class="token punctuation">.</span><span class="token function">appendChild</span><span class="token punctuation">(</span>imgEle<span class="token punctuation">)</span>
  <span class="token keyword">return</span> <span class="token punctuation">{</span>
    <span class="token function-variable function">setSrc</span><span class="token operator">:</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">src</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      imgEle<span class="token punctuation">.</span>src <span class="token operator">=</span> src
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

<span class="token comment">// 代理</span>
<span class="token keyword">var</span> proxyImage <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">var</span> img <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Image</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  img<span class="token punctuation">.</span><span class="token function-variable function">onload</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    domImage<span class="token punctuation">.</span><span class="token function">setSrc</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>src<span class="token punctuation">)</span> <span class="token comment">// 图片加载完设置真实图片src</span>
  <span class="token punctuation">}</span>
  <span class="token keyword">return</span> <span class="token punctuation">{</span>
    <span class="token function-variable function">setSrc</span><span class="token operator">:</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">src</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      domImage<span class="token punctuation">.</span><span class="token function">setSrc</span><span class="token punctuation">(</span><span class="token string">'./loading.gif'</span><span class="token punctuation">)</span> <span class="token comment">// 预先设置图片src为loading图</span>
      img<span class="token punctuation">.</span>src <span class="token operator">=</span> src
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

<span class="token comment">// 外部调用</span>
proxyImage<span class="token punctuation">.</span><span class="token function">setSrc</span><span class="token punctuation">(</span><span class="token string">'./product.png'</span><span class="token punctuation">)</span>
</code></pre></div><h4 id="什么时候用代理模式"><a href="#什么时候用代理模式" class="header-anchor">#</a> 什么时候用代理模式？</h4> <p>当你负责的模块，基本满足以下情况时</p> <ul><li>模块职责单一且可复用</li> <li>两个模块间的交互需要一定限制关系</li></ul> <blockquote><p>这里我又知道你有疑问了，关于 代理模式 VS 装饰者模式，这里我不讲它们的区分，下期再聊，或者自行资料查询</p></blockquote> <h3 id="题目五"><a href="#题目五" class="header-anchor">#</a> 题目五</h3> <p>需求 ：如图所示，我们申请设备之后，接下来要选择收货地址，然后选择责任人，而且必须是上一个成功，才能执行下一个~</p> <p><img src="https://user-gold-cdn.xitu.io/2020/4/26/171b62c5e590a228?imageView2/0/w/1280/h/960/format/webp/ignore-error/1" alt=""></p> <p>小伙伴们惊讶了，这不简单嘛？奥力给！</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">applyDevice</span><span class="token punctuation">(</span><span class="token parameter">data</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// 处理巴拉巴拉...</span>
  <span class="token keyword">let</span> devices <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
  <span class="token keyword">let</span> nextData <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">assign</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> data<span class="token punctuation">,</span> devices<span class="token punctuation">)</span>
  <span class="token comment">// 执行选择收货地址</span>
  <span class="token function">selectAddress</span><span class="token punctuation">(</span>nextData<span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token keyword">function</span> <span class="token function">selectAddress</span><span class="token punctuation">(</span><span class="token parameter">data</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// 处理巴拉巴拉...</span>
  <span class="token keyword">let</span> address <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
  <span class="token keyword">let</span> nextData <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">assign</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> data<span class="token punctuation">,</span> address<span class="token punctuation">)</span>
  <span class="token comment">// 执行选择责任人</span>
  <span class="token function">selectChecker</span><span class="token punctuation">(</span>nextData<span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token keyword">function</span> <span class="token function">selectChecker</span><span class="token punctuation">(</span><span class="token parameter">data</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// 处理巴拉巴拉...</span>
  <span class="token keyword">let</span> checker <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
  <span class="token keyword">let</span> nextData <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">assign</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> data<span class="token punctuation">,</span> checker<span class="token punctuation">)</span>
  <span class="token comment">// 还有更多</span>
<span class="token punctuation">}</span>
</code></pre></div><p>你看，这不就完事了，有啥难的，然后过了第二天，你又接了两个新的流程需求，可能一个就两步骤，一个可能多了 “检查库存” 这个步骤</p> <p><img src="https://user-gold-cdn.xitu.io/2020/4/26/171b62d2c2d48369?imageView2/0/w/1280/h/960/format/webp/ignore-error/1" alt=""></p> <p>你不由惊了，哎呀妈呀，<strong>老夫聊发少年狂，键盘伺候，Ctrl C + Ctrl V</strong>，直接 copy 然后改一下逻辑？？</p> <p>这里就是要讲的责任链模式。</p> <h4 id="责任链模式"><a href="#责任链模式" class="header-anchor">#</a> 责任链模式</h4> <p>什么是责任链模式呢？我给你们找了个定义 : 避免请求发送者与接收者耦合在一起，让多个对象都有可能接收请求，将这些对象连接成一条链，并且沿着这条链传递请求，直到有对象处理它为止。</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">const</span> <span class="token function-variable function">Chain</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">fn</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">this</span><span class="token punctuation">.</span>fn <span class="token operator">=</span> fn

  <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function-variable function">setNext</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>

  <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function-variable function">run</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">const</span> <span class="token function-variable function">applyDevice</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token keyword">const</span> chainApplyDevice <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Chain</span><span class="token punctuation">(</span>applyDevice<span class="token punctuation">)</span>

<span class="token keyword">const</span> <span class="token function-variable function">selectAddress</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token keyword">const</span> chainSelectAddress <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Chain</span><span class="token punctuation">(</span>selectAddress<span class="token punctuation">)</span>

<span class="token keyword">const</span> <span class="token function-variable function">selectChecker</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token keyword">const</span> chainSelectChecker <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Chain</span><span class="token punctuation">(</span>selectChecker<span class="token punctuation">)</span>

<span class="token comment">// 运用责任链模式实现上边功能</span>
chainApplyDevice<span class="token punctuation">.</span><span class="token function">setNext</span><span class="token punctuation">(</span>chainSelectAddress<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">setNext</span><span class="token punctuation">(</span>chainSelectChecker<span class="token punctuation">)</span>
chainApplyDevice<span class="token punctuation">.</span><span class="token function">run</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
</code></pre></div><p>这样的好处是啥？首先是解耦了各节点关系，之前的方式是 A 里边要写 B，B 里边写 C，但是这里不同了，你可以在 B 里边啥都不写。</p> <p>其次，各节点灵活拆分重组，正如上边你接的两个新需求。比如两个步骤的你就只需要这么写完事</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">const</span> <span class="token function-variable function">applyLincense</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token keyword">const</span> chainApplyLincense <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Chain</span><span class="token punctuation">(</span>applyLincense<span class="token punctuation">)</span>

<span class="token keyword">const</span> <span class="token function-variable function">selectChecker</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token keyword">const</span> chainSelectChecker <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Chain</span><span class="token punctuation">(</span>selectChecker<span class="token punctuation">)</span>

<span class="token comment">// 运用责任链模式实现上边功能</span>
chainApplyLincense<span class="token punctuation">.</span><span class="token function">setNext</span><span class="token punctuation">(</span>chainSelectChecker<span class="token punctuation">)</span>
chainApplyLincense<span class="token punctuation">.</span><span class="token function">run</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
</code></pre></div><h4 id="什么时候使用责任链模式"><a href="#什么时候使用责任链模式" class="header-anchor">#</a> 什么时候使用责任链模式？</h4> <p>当你负责的模块，基本满足以下情况时</p> <ul><li>你负责的是一个完整流程，或你只负责流程中的某个环节</li> <li>各环节可复用</li> <li>各环节有一定的执行顺序</li> <li>各环节可重组</li></ul> <h2 id="结尾"><a href="#结尾" class="header-anchor">#</a> 结尾</h2> <p>不知不觉，又是给大家撸了一篇设计模式的文章，设计模式真的很重要，虽然说我也刚领悟其中的一丝诀窍，<strong>但是我想，可能还有很多跟我一样，在设计模式门槛外，迟迟无法顿悟的小伙伴</strong>，我是一个很烦看长篇大论的人，之前也看了设计模式相关书籍，初次看还能耐心看下去，但是去看别人博客、文章的时候，看到好多定义、好多理论，包括一些举的 🌰，感觉当时懂了，但是在开发中，我还是不知道怎么用...</p> <p>不是让大家强行套用设计模式，而是想表达 : 我们首先需要理解，其次需要形成一种肌肉记忆，正如前边说的策略模式、发布 - 订阅模式的例子一样，大家在真实开发场景中肯定都有遇到，只是没有想到，原来这就是设计模式，或者说，原来这里可以用到设计模式去设计。</p> <p>这篇文章，其中三个题目来自潇哥分享的 PPT，并且思维导图也是他画的，经过他的同意，我将其整理成了一篇文章，同时结合我自己的理解，尽可能以一种幽默、风趣、易懂的形式，跟大家唠嗑唠嗑一下，<strong>如果我有说的不对或者存在误解的地方，欢迎大家指出</strong>~ Thank you ~</p> <p>对了，前几天写了一篇 <a href="https://juejin.im/post/5e8d4300f265da47f85de3db" target="_blank" rel="noopener noreferrer">前端渣渣的我再也不敢说我会写 Button 组件了<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> 文章，然后发现被人转到个人公众号了，要不是学弟告知我，我还不知道原来我的文章被公众号营销给转走了。虽然备注了原文出处，但是还是想说，你转我的文章，最起码评论区里知会一声吧~</p> <p>看过我文章的小伙伴都知道，我几乎是一个月才更一两篇博客，不是我不想更新，而是我想做有生命有活力的文章，是真的有去了解、去做实践、去看源码，然后一字一字的在电脑桌前，整理成一篇<strong>算得上能有一丝帮助</strong>的文章，写这么一篇，可能就需要我一下午甚至一天的时间，你倒好，直接 Ctrl C + Ctrl V，把我文章抄过去了，然后再贴个原文链接，我...</p> <p>我不是不允许你转，你最起码告知我一声吖~ 我 : ？？？？？？？</p> <p><img src="https://user-gold-cdn.xitu.io/2020/4/26/171b6505d8a77fdd?imageView2/0/w/1280/h/960/format/webp/ignore-error/1" alt=""></p> <p>算了算了，不说了，感谢看官看到这里，文中源码我放这里了 <a href="https://github.com/PDKSophia/DesignPatternsToJS/tree/master/eaxmple" target="_blank" rel="noopener noreferrer">设计模式 demo 源码<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>，想看的自取 ~</p> <h2 id="相关链接"><a href="#相关链接" class="header-anchor">#</a> 相关链接</h2> <ul><li><a href="https://github.com/PDKSophia/blog.io" target="_blank" rel="noopener noreferrer">阿宽的博客<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li><a href="https://juejin.im/user/5b88a73ce51d453884363524" target="_blank" rel="noopener noreferrer">苏格团队<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></div> <footer class="page-edit"><!----> <div class="last-updated"><span class="prefix">更新于:</span> <span class="time">8/7/2021, 12:01:15 AM</span></div></footer> <div class="page-nav"><p class="inner"><span class="prev">
      ←
      <a href="/front-end/javascript.html" class="prev">
        Javascript/ECMAScript 相关技术
      </a></span> <span class="next"><a href="/front-end/typescript.html">
        学习 Typescript 实战开发
      </a>
      →
    </span></p></div> </main></div><div class="global-ui"><!----></div></div>
    <script src="/assets/js/app.adf242e6.js" defer></script><script src="/assets/js/2.8cf67c90.js" defer></script><script src="/assets/js/22.a1f4c10c.js" defer></script>
  </body>
</html>
